package com.harveyspace.aes.social.steam;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.harveyspace.aes.core.utils.HttpUtil;
import com.harveyspace.aes.core.utils.JsonUtil;
import com.harveyspace.aes.social.Oauth;
import com.harveyspace.aes.social.SocialConfig;
import com.harveyspace.aes.social.exception.SocialException;
import com.harveyspace.aes.social.pojo.AccessTokenInfo;
import com.harveyspace.aes.social.pojo.SocialiteUserInfo;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;

/**
 * steam
 *
 * @Author <a href="harveyer@163.com">harvey</a>
 * @date 2018/2/9
 */
public class OauthSteam extends Oauth {

    private final String AUTH_URL = "https://steamcommunity.com/openid/login";
    private final String NS_URL = "http://specs.openid.net/auth/2.0";
    private final String NS_IDENTITY_URL = "http://specs.openid.net/auth/2.0/identifier_select";

    private final String USER_INFO_URL = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/";

    /**
     * @param socialConfig 配置信息
     */
    public OauthSteam(SocialConfig socialConfig) {
        super(socialConfig);
    }

    /**
     * 获取授权url
     *
     * @return String url
     */
    @Override
    public String getAuthorizeUrl(String state) {

        Map<String, String> params = new HashMap<>();
        params.put("openid.ns", NS_URL);
        params.put("openid.mode", "checkid_setup");
        params.put("openid.return_to", socialConfig.getRedirectUri());
        params.put("openid.realm", socialConfig.getRedirectUri());
        params.put("openid.identity", NS_IDENTITY_URL);
        params.put("openid.claimed_id", NS_IDENTITY_URL);

        return initParams(AUTH_URL, params);
    }

    /**
     * 获取UserInfo
     *
     * @param accessToken AccessToken
     * @param openId      openid
     * @return String 返回类型
     * @throws SocialException 获取用户信息异常
     */
    private SteamUserInfo getUserInfo(String accessToken, String openId) throws SocialException {

        Map<String, String> params = new HashMap<>();
        params.put("key", socialConfig.getClientSecret());
        params.put("steamids", openId);

        String result;
        try {
            result = HttpUtil.getString(initParams(USER_INFO_URL, params), 1);
        } catch (IOException e) {
            String errorMessage = String.format("通过 accessToken[%s]，openid[%s] 获取用户信息异常", accessToken, openId);
            logger.error(errorMessage, e);
            throw new SocialException(errorMessage);
        }

        JsonElement jsonElement = null;
        try {
            JsonObject jsonObject = JsonUtil.toJsonObject(result);
            jsonElement = jsonObject.getAsJsonObject("response")
                    .getAsJsonArray("players")
                    .get(0);
        } catch (NullPointerException e) {}

        return JsonUtil.toObject(jsonElement, SteamUserInfo.class);
    }

    @Override
    public AccessTokenInfo getAccessToken(Map<String, String> request) {

        Object signed = request.get("openid.signed");

        if (signed == null || "".equals(signed)) {
            return null;
        }

        String steamid = request.get("openid.claimed_id");
        steamid = steamid.replace("https://steamcommunity.com/openid/id/", "");

        AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
        accessTokenInfo.setOpenId(steamid);
        accessTokenInfo.setUnionId(steamid);
        accessTokenInfo.setAccessToken(request.get("openid.sig"));

        return accessTokenInfo;
    }

    @Override
    public SocialiteUserInfo getSocialUserInfo(AccessTokenInfo accessTokenInfo) throws SocialException {

        String accessToken = accessTokenInfo.getAccessToken();
        String openId = accessTokenInfo.getOpenId();

        if (StringUtils.isBlank(accessToken)) {
            throw new SocialException("accessToken is Blank!");
        }

        if (StringUtils.isBlank(openId)) {
            throw new SocialException("openId is Blank!");
        }

        SocialiteUserInfo socialiteUserInfo = new SocialiteUserInfo();
        socialiteUserInfo.setUnionId(accessTokenInfo.getUnionId());
        socialiteUserInfo.setOpenId(accessTokenInfo.getOpenId());

        SteamUserInfo info = getUserInfo(accessToken, openId);

        if (null != info) {
            socialiteUserInfo.setAvatar(info.getAvatarmedium());
            socialiteUserInfo.setNickName(info.getPersonaname());
            socialiteUserInfo.setName(info.getPersonaname());
        }

        return socialiteUserInfo;
    }
}